<?php

namespace App\Modules\Apicrzs\Services\Water;

use App\Library\Junda\src\EquipmentService;
use App\Modules\Admin\Entities\Equipment\EquipmentParamsFreeModel;
use App\Modules\Admin\Entities\Log\WaterDeviceLogModel;
use App\Modules\Admin\Entities\Log\WaterDeviceOnlineLogModel;
use App\Modules\Admin\Entities\Member\UsersModel;
use App\Modules\Admin\Entities\Water\WaterDeviceModel;
use App\Modules\Admin\Entities\Water\WaterWithUserModel;
use App\Modules\Apicrzs\Services\BaseServices;
use App\Traits\CryptAES;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;

class WaterDeviceService extends BaseServices
{
//    public function __construct(ApparatusModel $model)
    public function __construct(WaterDeviceModel $model)
    {
        $token = \request()->header('token');
        $user_info = CryptAES::decryptToken($token, 'user_grzq');
        $this->user_id = $user_info['data']['user_id'] ?? "";
        $this->model = $model;
    }

    public function getLists($params)
    {
        #经度
        $all = $params["all"] ?? "";
        $lng = $params["lng"] ?? "";
        #纬度
        $lat = $params["lat"] ?? "";
        #获取指定范围的数据单位km
        $distance_sea = 100;
        #数据模型
        $model = $this->model->where(['status' => 1]);
        if (!empty($lng)) {
            $distance = "ACOS(SIN(( $lat * 3.1415) / 180 ) *SIN((lat * 3.1415) / 180 ) +COS(( $lat* 3.1415) / 180 ) * COS((lat * 3.1415) / 180 ) *COS(( $lng* 3.1415) / 180 - (lng * 3.1415) / 180 ) ) * 6380";
            $model->select(['water_id', 'water_title', 'address', 'lng', 'lat']);
            $model->addSelect(DB::raw($distance . ' as distance'))->orderBy('distance', 'ASC');
#控制范围
            $model->whereRaw($distance . "<" . $distance_sea);
        }else{
            $model->select(['water_id', 'code','water_title', 'address', 'lng', 'lat']);
            $model->orderBy($this->model->getKeyName(), 'DESC');
        }
        $lists_data=[];
        if ($all=='all'){
            $lists_items = $model->get()->toArray();
        }else{
            $lists = $model->paginate($this->getLimit($params['limit'] ?? 10));
            $lists_items = $lists->items();
        }

        foreach ($lists_items as $item) {
            $lists_data[] = [
                'id' => $item['water_id'],
                'title' => $item['water_title'],
                'code' => $item['code'],
                'address' => $item['address'],
                'lng' => $item['lng'],
                'lat' => $item['lat'],
                'distance' => isset($item['distance'])? (sprintf("%.2f", $item['distance']) ??0). "km":""
            ];
        }
        if ($all=='all'){
            $lists_data  =  $lists_items;
        }else{
            $lists_data = [
                'current_page' => $lists->currentPage(),//当前
                'per_page' => $lists->perPage(),//每页 10 条
                'count_page' => $lists->lastPage(),//
                'total' => $lists->total(), // 总数
                'data' => $lists_data,
            ];
        }

        return $lists_data;
    }

    // 水机 单个 单口 数据
    public function getEquipmentPlans($params)
    {
        $openid = $params['openid']??"";
        $water_id = $params['eid'];
        $type = $params['type'];



        $user_info = UsersModel::getInstance()->where(['openid'=>$openid])->with(['user_card'])->first();
        $lists = EquipmentParamsFreeModel::getInstance()->where(['water_id'=>$water_id,'ttype'=>$type])
            ->first(['id','water_id','title','water_title','money','equipment_id']);
       // $lists['money'] = $lists['money'];
        $lists['is_card'] = isset($user_info['user_card'])?(isset($user_info['user_card']['remaining_value'])?$user_info['user_card']['remaining_value']!='0.00':false):false;


        return $lists;
    }

    public function getApparatusCount($userId){
        $user_id = $this->user_id;
        $apparatusList =  WaterWithUserModel::getInstance()->getUserWithWaterByIds($user_id);
        $count = count($apparatusList);
        return ['count' => $count];
    }

    public function getCacheEquipmentCheckPay($params)
    {
        set_time_limit(0);
        $equipment_list = Cache::get('water:device:job_cache:equipment');
        foreach ($equipment_list as $equipment_id){
            //检测设备状态是否可以消费
            $checkPay = EquipmentService::CheckEqBeforePay($equipment_id);

            $equipment_info = Cache::get('water:device:job_cache:eq_all:'.$equipment_id);
            $water_title = $equipment_info['water_title'];
            $water_id = $equipment_info['water_id'];
            $water_device_info  = WaterDeviceModel::getInstance()->getSelectListsByWaterId($water_id);
            $water_title = $water_device_info['water_title'];
            $water_id = $water_device_info['water_id'];
            $water_type = $equipment_info['title'];

            $status_check = $checkPay['success']==true?1:2;
            $log_id =  WaterDeviceLogModel::getInstance()->addLog([
                'user_id'=>$this->user_id,
                'water_id'=>$water_id,
                'water_title'=>$water_title,
                'type'=>$water_type,
                'status'=>$status_check,
                'msg'=>$checkPay['msg'],
                'remark'=>$checkPay,
            ]);

//            $check_msg = $checkPay['msg'];
//
//            $water_id = $equipment_info['water_id'];
//            if (!$checkPay['success']) {
//                $check_msg = $checkPay['msg'];
//                if (strstr($check_msg, '设备正忙')) {
//                    $msg = "上笔订单未结束,出水口关灯后";
//                    WaterDeviceOnlineLogModel::getInstance()->createOnlineLog($water_id,$water_title,'error_busy');
//                }else{
//                    $msg = "通讯失败或信号不稳定";
//                    WaterDeviceOnlineLogModel::getInstance()->createOnlineLog($water_id,$water_title,'error_failed');
//                }
//
//                $this->error = $checkPay['msg'].'，请重新扫码';
//                $checkPay['online_name'] = '请稍后，正在与设备连接中';
//                $checkPay['water_title'] = $water_title;
//                xdebug($checkPay,'骏达-检测设备是否可以消费-返回状态 - 02 '.$water_title,'cache-checkPay/error',$water_title);
//                //return ['check'=>false,'msg'=>$msg.',请重新扫码'];
//            }else{
//                xdebug($checkPay,'骏达-检测设备是否可以消费-返回状态 - 02 '.$water_title,'cache-checkPay/success',$water_title);
//                WaterDeviceOnlineLogModel::getInstance()->createOnlineLog($water_id,$water_title,'success');
//            }
        }

        exit(json_encode($equipment_list));
    }
    /**
     *  检测设备
     *  检测设备状态是否可以消费
     * @param $params
     * @return bool
     */
    public function getEquipmentCheckPay($params)
    {
        $current =  time();
        $status = strtotime('2025-05-25 23:50:00');
        $end = strtotime('2025-05-27 03:50:00');
        if ($current >= $status && $current <= $end) {
            return ['check'=>false,'msg'=>'系统升级，暂停时间：2025-05-26 23:50 至 2025-05-27 03:50；扫码暂停'];
        }
        $fee_id = $params['fee_id'] ?? "";

        if (!$fee_id) {
            return ['check'=>false,'msg'=>'参数错误'];
        }

        xdebug($params,'检测设备参数-fee_id - 01','','online/params');
        $paramsFreeInfo = EquipmentParamsFreeModel::getInstance()->getFreeByid($fee_id);
        xdebug($paramsFreeInfo,'设备数据-','','online/params');
        if (!$paramsFreeInfo) {
            return ['check'=>false,'msg'=>'参数错误'];
        }
        $equipment_id = $paramsFreeInfo['equipment_id'];
        $water_device_info  = WaterDeviceModel::getInstance()->getSelectListsByWaterId($paramsFreeInfo['water_id']);
        $water_title = $water_device_info['water_title'];
        $water_id = $water_device_info['water_id'];
        $water_type = $paramsFreeInfo['title'];

        //检测设备状态是否可以消费
        $checkPay = EquipmentService::CheckEqBeforePay($equipment_id);

        $status_check = $checkPay['success']==true?1:2;
       $log_id =  WaterDeviceLogModel::getInstance()->addLog([
            'user_id'=>$this->user_id,
            'water_id'=>$water_id,
            'water_title'=>$water_title,
            'type'=>$water_type,
            'status'=>$status_check,
            'msg'=>$checkPay['msg'],
            'remark'=>$checkPay,
        ]);

        xdebug($checkPay,'骏达-检测设备状态是否可以消费 - 02 【'.$water_title,'','online/count');
        $check_success = false;
        $check_error_msg = '设备通讯正常';
        if (!$checkPay['success']) {
            $check_msg = $checkPay['msg'];
            if (strstr($check_msg, '设备正忙')) {
                $check_error_msg = "上笔订单未结束,出水口关灯后";
                WaterDeviceOnlineLogModel::getInstance()->createOnlineLog($water_id,$water_title,'error_busy');
                $this->setSendMessage2DingTalk('通讯失败：',$fee_id,$checkPay,$water_id,$water_title,$check_error_msg);
                xdebug($checkPay,'骏达-检测设备是否可以消费-返回状态 - 02 '.$water_title,'','online/error_busy');
                $check_success = false;
            }else{
                if (strstr($check_msg, '缺水')) {
                    $check_error_msg = "水机内缺水，请稍后扫码";
                }else{
                    $check_error_msg = "通讯失败或信号不稳定";
                }
                WaterDeviceOnlineLogModel::getInstance()->createOnlineLog($water_id,$water_title,'error_failed');
                $this->setSendMessage2DingTalk('通讯失败：',$fee_id,$checkPay,$water_id,$water_title,$check_error_msg);
                xdebug($checkPay,'骏达-检测设备是否可以消费-返回状态 - 02 '.$water_title,'','online/error_failed');
                $check_success = false;
            }
        }else{
            $check_success = true;
            xdebug($checkPay,'骏达-检测设备是否可以消费-返回状态 - 02 '.$water_title,'','online/success');
            WaterDeviceOnlineLogModel::getInstance()->createOnlineLog($water_id,$water_title,'success');
        }
        return ['check'=>$check_success,'log_id'=>$log_id,'msg'=>$check_error_msg];
    }

    // 钉钉通讯
    public function setSendMessage2DingTalk($title,$fee_id,$checkPay,$water_id,$water_title,$msg){
        $checkPay['online_name'] = '请稍后，正在与设备连接中';
        $checkPay['water_title'] = $water_title;
        $this->sendMessage2DingTalk(
            $title .
            "  \n 扫码打水，系统与水机通讯状态通知：" .
            "  \n 时间：" . date('Y-m-d H:i:s').
            "  \n 水机编号：" . $water_id. "/".$fee_id.
            "  \n 水机名称： " . $water_title.
            "  \n 提示内容： " . $msg.
//            "  \n  询结果:\n  " . $resStr .
            "  \n  骏达返回通讯失败状态：\n" . json_encode($checkPay,JSON_UNESCAPED_UNICODE) . '：；'
        );
        xdebug($checkPay,'骏达-检测设备是否可以消费-返回状态 - 02 '.$water_title,'','online/error');
        return true;
    }
    public function sendMessage2DingTalk($content)
    {
        $dingtalk_robot = [
            '1'=>[
                'access_token'=>'a9251b8d6e3f22c25b730b60d4cb1474b955a033f49cd45735c6c4a1f8a956e9',
                'secret'=>'SECc31a362a4889dfdfeb886946b9963dbf7edcfed78eb47b927237b2e151f1270c'
            ],
            '2'=>[
                'access_token'=>'03e9c08f5cbb49c72b19faf1d112d63382e49ccbe44fa5239935123c3bf5f540',
                'secret'=>'SEC52edfd457934a884e1069d9f8ab7fde245b757c77bb17af83a4d598a3f04f183'
            ],
            '3'=>[
                'access_token'=>'510ef59172014e755ee3958b6f7302c2d0091adb45c7f745fa6f35d8c32d81f7',
                'secret'=>'SEC1d5aaa8744fa7a0a4bf9ec15aa7b3b2df4cc0de45b1ad5acc820506b008ca04c'
            ],
        ];
        $access_token=$dingtalk_robot[1]['access_token'];
        $url = 'https://oapi.dingtalk.com/robot/send?access_token='.$access_token;
        $secret=$dingtalk_robot[1]['secret'];
//        $url = 'webhook地址';
// 第一步，把timestamp+"\n"+密钥当做签名字符串，使用HmacSHA256算法计算签名，然后进行Base64 encode，最后再把签名参数再进行urlEncode，得到最终的签名（需要使用UTF-8字符集）。
        $time = time() *1000;//毫秒级时间戳，我这里为了方便，直接把时间*1000了
        $sign = hash_hmac('sha256', $time . "\n" . $secret,$secret,true);
        $sign = base64_encode($sign);
        $sign = urlencode($sign);
        $msg = [
            'msgtype' => 'text',//这是文件发送类型，可以根据需求调整
            'text'    => [
                'content' => $content,
            ],
        ];
        $url = "{$url}&timestamp={$time}&sign={$sign}";
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($msg));
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $res = curl_exec($curl);
        curl_close($curl);
        return json_decode($res,true);
    }
}
